/**
 * @description 股票预测服务 - 基于30年股票交易经验的分析系统
 */
class PredictionService {
  /**
   * @description 生成股票预测
   * @param {Array} stocks 股票列表
   */
  async generatePredictions(stocks) {
    return Promise.all(
      stocks.map(async (stock) => {
        const score = this.calculateScore(stock)
        return {
          ...stock,
          predictionScore: parseFloat(score.toFixed(2)),
          recommendation: this.getRecommendation(score)
        }
      })
    )
  }

  /**
   * @description 计算综合预测得分
   */
  calculateScore(stock) {
    const {
      changePercent,    // 当日涨跌幅
      volumeRatio,      // 量比
      turnoverRate,     // 换手率
      pe,              // 市盈率
      threeDayChange,   // 3日涨跌幅
      fiveDayChange,    // 5日涨跌幅
      limitUpDays      // 连续涨停天数
    } = stock

    // 1. 趋势动量分析 (35%)
    const momentumScore = this.analyzeMomentum(changePercent, threeDayChange, fiveDayChange)

    // 2. 成交量分析 (25%)
    const volumeScore = this.analyzeVolume(volumeRatio, turnoverRate, changePercent)

    // 3. 估值分析 (20%)
    const valuationScore = this.analyzeValuation(pe)

    // 4. 技术形态分析 (20%)
    const technicalScore = this.analyzeTechnicalPattern(changePercent, threeDayChange, fiveDayChange, volumeRatio, limitUpDays)

    // 综合得分
    return (
      momentumScore * 0.35 +
      volumeScore * 0.25 +
      valuationScore * 0.20 +
      technicalScore * 0.20
    ) * 100
  }

  /**
   * @description 趋势动量分析
   * 分析股票的短期、中期趋势和动量
   */
  analyzeMomentum(changePercent, threeDayChange, fiveDayChange) {
    // 当日涨跌
    const dayScore = changePercent > 0 ? 
      Math.min(changePercent / 8, 1) : // 8%为满分
      Math.max(-0.5, changePercent / 8) // 最低-0.5分

    // 三日趋势
    const threeDayScore = threeDayChange > 0 ?
      Math.min(threeDayChange / 15, 1) : // 15%为满分
      Math.max(-0.5, threeDayChange / 15)

    // 五日趋势
    const fiveDayScore = fiveDayChange > 0 ?
      Math.min(fiveDayChange / 20, 1) : // 20%为满分
      Math.max(-0.5, fiveDayChange / 20)

    // 趋势一致性加分
    const trendConsistency = (
      Math.sign(changePercent) === Math.sign(threeDayChange) &&
      Math.sign(threeDayChange) === Math.sign(fiveDayChange)
    ) ? 0.2 : 0

    return (
      dayScore * 0.4 +
      threeDayScore * 0.3 +
      fiveDayScore * 0.3 +
      trendConsistency
    )
  }

  /**
   * @description 成交量分析
   * 分析成交量的变化和与价格的配合关系
   */
  analyzeVolume(volumeRatio, turnoverRate, changePercent) {
    // 量比分析
    const volumeRatioScore = volumeRatio > 1 ?
      Math.min((volumeRatio - 1) / 2, 1) : // 量比3为满分
      Math.max(0, (volumeRatio - 0.5) / 0.5) // 量比低于0.5为0分

    // 换手率分析
    const turnoverScore = Math.min(turnoverRate / 8, 1) // 8%换手率为满分

    // 量价配合分析
    const volumePriceMatch = (
      (changePercent > 0 && volumeRatio > 1.5) || // 上涨放量
      (changePercent < 0 && volumeRatio < 0.8)    // 下跌缩量
    ) ? 0.2 : 0

    return (
      volumeRatioScore * 0.4 +
      turnoverScore * 0.4 +
      volumePriceMatch
    )
  }

  /**
   * @description 估值分析
   * 分析股票的估值水平
   */
  analyzeValuation(pe) {
    if (pe <= 0) return 0.3 // PE为负数，给予较低分数

    // PE估值区间评分
    if (pe < 15) return 1      // PE < 15，低估
    if (pe < 25) return 0.8    // 15 <= PE < 25，合理
    if (pe < 35) return 0.6    // 25 <= PE < 35，偏高
    if (pe < 50) return 0.4    // 35 <= PE < 50，高估
    if (pe < 100) return 0.2   // 50 <= PE < 100，严重高估
    return 0                    // PE >= 100，不建议
  }

  /**
   * @description 技术形态分析
   * 分析股票的技术形态特征
   */
  analyzeTechnicalPattern(changePercent, threeDayChange, fiveDayChange, volumeRatio, limitUpDays) {
    // 连板风险评估
    const limitUpRisk = limitUpDays > 3 ? -0.2 : // 超过3板风险较大
      limitUpDays > 0 ? 0.1 : 0 // 1-3板有一定机会

    // 反转信号
    const reversalSignal = (
      (fiveDayChange < -8 && threeDayChange > 0) || // 超跌反弹
      (fiveDayChange > 12 && threeDayChange < 0)    // 超涨回调
    ) ? 0.3 : 0

    // 突破信号
    const breakoutSignal = (
      (changePercent > 5 && threeDayChange > 0) ||  // 连续上涨
      (threeDayChange > 8 && fiveDayChange > 12)    // 持续上攻
    ) ? 0.4 : 0

    // 趋势延续信号
    const trendContinuation = (
      Math.sign(changePercent) === Math.sign(threeDayChange) &&
      Math.abs(changePercent) > 2 &&
      Math.abs(threeDayChange) > 5
    ) ? 0.3 : 0

    return Math.max(
      reversalSignal,
      breakoutSignal,
      trendContinuation,
      0.2 // 基础分
    ) + limitUpRisk // 加入连板风险因素
  }

  /**
   * @description 获取推荐建议
   */
  getRecommendation(score) {
    if (score >= 90) return '强烈推荐'     // 各项指标都很优秀
    if (score >= 80) return '建议买入'     // 大部分指标表现良好
    if (score >= 70) return '可以关注'     // 有一定投资价值
    if (score >= 60) return '需要观察'     // 观察变化趋势
    if (score >= 50) return '保持观望'     // 等待更好时机
    if (score >= 40) return '注意风险'     // 存在一定风险
    return '建议规避'                      // 风险较大
  }
}

module.exports = { PredictionService } 